﻿namespace Foggy.ViewModels
{
    using System.Collections.ObjectModel;
    using System.Linq;

    using Caliburn.Micro;

    using Foggy.Data.Users;
    using Foggy.Settings;
    using Foggy.Users;

    using User = Foggy.Users.User;

    /// <summary>
    /// Settings view model
    /// </summary>
    public sealed class SettingsViewModel : Screen
    {
        /// <summary>
        /// The FogBugz URL
        /// </summary>
        private string fogBugzUrl;

        /// <summary>
        /// The login username
        /// </summary>
        private string loginUsername;

        /// <summary>
        /// The login password
        /// </summary>
        private string loginPassword;

        /// <summary>
        /// The user collection
        /// </summary>
        private ObservableCollection<User> users;

        /// <summary>
        /// The selected user
        /// </summary>
        private UserDto selectedUser;

        /// <summary>
        /// The new user email
        /// </summary>
        private string newUserEmail;

        /// <summary>
        /// Initializes a new instance of the <see cref="SettingsViewModel" /> class.
        /// </summary>
        /// <param name="settingsService">The settings service.</param>
        /// <param name="userService">The user service.</param>
        public SettingsViewModel(ISettingsService settingsService, IUserService userService)
        {
            this.DisplayName = "Settings";

            this.SettingsService = settingsService;
            this.UserService = userService;
        }

        /// <summary>
        /// Gets or sets the settings service.
        /// </summary>
        /// <value>
        /// The settings service.
        /// </value>
        public ISettingsService SettingsService { get; set; }

        /// <summary>
        /// Gets or sets the user service.
        /// </summary>
        /// <value>
        /// The user service.
        /// </value>
        public IUserService UserService { get; set; }

        /// <summary>
        /// Gets or sets the fog bugz URL.
        /// </summary>
        /// <value>
        /// The fog bugz URL.
        /// </value>
        public string FogBugzUrl
        {
            get
            {
                return this.fogBugzUrl;
            }

            set
            {
                this.fogBugzUrl = value;
                this.NotifyOfPropertyChange(() => this.FogBugzUrl);
                this.NotifyOfPropertyChange(() => this.FogBugzApiUrl);
            }
        }

        /// <summary>
        /// Gets or sets the login username.
        /// </summary>
        /// <value>
        /// The login username.
        /// </value>
        public string LoginUsername
        {
            get
            {
                return this.loginUsername;
            }

            set
            {
                this.loginUsername = value;
                this.NotifyOfPropertyChange(() => this.LoginUsername);
            }
        }

        /// <summary>
        /// Gets or sets the login password.
        /// </summary>
        /// <value>
        /// The login password.
        /// </value>
        public string LoginPassword
        {
            get
            {
                return this.loginPassword;
            }

            set
            {
                this.loginPassword = value;
                this.NotifyOfPropertyChange(() => this.LoginPassword);
            }
        }

        /// <summary>
        /// Gets the fog bugz API URL.
        /// </summary>
        /// <value>
        /// The fog bugz API URL.
        /// </value>
        public string FogBugzApiUrl
        {
            get
            {
                return string.Format("{0}/api.asp", this.FogBugzUrl);
            }
        }

        /// <summary>
        /// Gets or sets the selected user.
        /// </summary>
        /// <value>
        /// The selected user.
        /// </value>
        public UserDto SelectedUser
        {
            get
            {
                return this.selectedUser;
            }

            set
            {
                this.selectedUser = value;
                this.NotifyOfPropertyChange(() => this.SelectedUser);
            }
        }

        /// <summary>
        /// Gets or sets the new user email.
        /// </summary>
        /// <value>
        /// The new user email.
        /// </value>
        public string NewUserEmail
        {
            get
            {
                return this.newUserEmail;
            }

            set
            {
                this.newUserEmail = value;
                this.NotifyOfPropertyChange(() => this.NewUserEmail);
            }
        }

        /// <summary>
        /// Gets or sets the users.
        /// </summary>
        /// <value>
        /// The users.
        /// </value>
        public ObservableCollection<User> Users
        {
            get
            {
                return this.users;
            }

            set
            {
                this.users = value;
                this.NotifyOfPropertyChange(() => this.Users);
            }
        }

        /// <summary>
        /// Cancels this instance.
        /// </summary>
        public void Cancel()
        {
            this.TryClose(false);
        }

        /// <summary>
        /// Oks this instance.
        /// </summary>
        public void Ok()
        {
            // Save settings
            this.SettingsService.SetSetting(Setting.FogBugzUrl, this.FogBugzUrl);
            this.SettingsService.SetSetting(Setting.LoginUsername, this.LoginUsername);
            this.SettingsService.SetSetting(Setting.LoginPassword, this.LoginPassword);

            // Save the users
            this.UserService.SaveUsers(this.Users);

            this.TryClose(true);
        }

        /// <summary>
        /// Adds the user.
        /// </summary>
        public void AddUser()
        {
            if (string.IsNullOrWhiteSpace(this.NewUserEmail))
            {
                return;
            }

            var existingUser = this.Users.Any(u => u.Email == this.NewUserEmail);

            if (existingUser)
            {
                return;
            }

            this.Users.Add(new User { Email = this.NewUserEmail });
            this.NewUserEmail = string.Empty;
        }

        /// <summary>
        /// Deletes the user.
        /// </summary>
        /// <param name="user">The user.</param>
        public void DeleteUser(User user)
        {
            if (user == null)
            {
                return;
            }

            if (this.Users.Contains(user))
            {
                this.Users.Remove(user);
            }
        }

        /// <summary>
        /// Called when activating.
        /// </summary>
        protected override void OnActivate()
        {
            base.OnActivate();

            // Load current settings
            this.FogBugzUrl = this.SettingsService.GetSettingOrDefault(Setting.FogBugzUrl, string.Empty);
            this.LoginUsername = this.SettingsService.GetSettingOrDefault(Setting.LoginUsername, string.Empty);
            this.LoginPassword = this.SettingsService.GetSettingOrDefault(Setting.LoginPassword, string.Empty);

            // Load current users
            var currentUsers = this.UserService.GetUsers();
            this.Users = new ObservableCollection<User>(currentUsers);            
        }
    }
}
